/*********************************************************************************
 *      Copyright:  (C) 2022 dairongan<2974932606@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  APP.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(07/24/2022)
 *         Author:  dairongan <2974932606@qq.com>
 *      ChangeLog:  1, Release initial version on "07/24/2022 06:34:21 PM"
 *                 
 ********************************************************************************/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <mosquitto.h>
#include <signal.h>

#include "oled_api.h"
#include "beep.h"
#include "get_temp.h"
#include "logger.h"
#include "parse_mqttini.h"
#include "cJSON.h"
#include "misc_api.h"


/*************全局变量********************/
int p_stop=0;		//判断程序是否继续运行标志

void sign_handle(int signum)
{
	p_stop=1;
}
void signal_init();

int main(int argc, char *argv[])
{
	int 					fd_oled,fd_sht20;
	int 					ret;
	int 					i=0;
	struct time_interval 	tm_intv={0,3};
	char 					*cloud_platform=NULL;
	float 					temp_f,hum_f;
	int 					beep_flag=0;
	int 					pub_con_flag=0;
	s_mosquitto_data 		mqtt_data;
	struct mosquitto 		*mosq = NULL;
	char 					databuf[128];
	enum					mqtt_server_con_flag
	{
							con_failed,
							con_success
	};

	if(!argv[1])
	{
		printf("Please input valid argument to connect server:\n"); 
		printf("The aliyun indicates Aliyun\n");
		printf("The tengxunyun indicates Tengxunyun\n");
		printf("The huaweiyun indicates Huaweiyun\n");
		printf("The test indicates Test\n");
		printf("For example:%s aliyun  ---connect to Aliyun\n", argv[0]);
		return 0;
	}

	cloud_platform=argv[1];

	memset(&mqtt_data,0,sizeof(mqtt_data));

	//读取配置文件
	if(ret=parse_mqtt_ini(cloud_platform,&mqtt_data)<0)
	{
		printf("Mqtt inisparser failed!\r\n");
		return -1;
	}
	
	tm_intv.interval = mqtt_data.interval;
	
	//初始化信号,并安装信号
	signal_init();

    //设置日志文件信息，初始化
    if( ret=logger_init(mqtt_data.log_name, LOG_LEVEL_INFO) < 0)
    {
        fprintf(stderr, "initial logger system failure\n");
        goto Cleanup_logger;
    }

	//mosquitto 初始化
	if( mosquitto_lib_init() != MOSQ_ERR_SUCCESS )      {
       	log_error( "mosquitto lib init failure:%s\n", strerror(errno) );
		goto Cleanup_mosq_lib;
    }

	//创建一个新的客户端
	mosq = mosquitto_new(mqtt_data.client_id, false, (void *)&mqtt_data);	
	if(!mosq)
	{
		log_error("Mosquitto new failure:%s\n", strerror(errno));
		ret=-1;
		goto Cleanup_mosq_obj;
	}

	//设置连接代理账号密码
	if(mosquitto_username_pw_set(mosq,mqtt_data.user,mqtt_data.password) != MOSQ_ERR_SUCCESS)
	{
		log_error("Mosquitto get username and password failure:%s\n", strerror(errno));
		ret = -1;
		goto Cleanup_mosq_obj;
	}

	mosquitto_message_callback_set(mosq,dra_message_callback);

	//打开oled设备文件
	fd_oled = oled_open();
	if(fd_oled < 0)
	{
		printf("open oled device file fail\r\n");
		ret = fd_oled;
		goto Cleanup_fd;
	}

	
	OLED_Clear(fd_oled);		//清屏

	oled_show_temp_hum_chinese(fd_oled);


    while(!p_stop)
    {
		OLED_updateTime(fd_oled);

		if(con_success!=pub_con_flag)//没连接上mqtt的docker
		{
			ret=mqtt_connect(mosq,&mqtt_data);	
			if(MOSQ_ERR_SUCCESS==ret)
			{
				pub_con_flag=con_success;	
				ret=subscribe_message(mosq,&mqtt_data);
				if(MOSQ_ERR_SUCCESS!=ret)
				{
					pub_con_flag=con_failed;
				}
			}
		}

		if(sampling_timer(&tm_intv))
		{
			//打印连接失败信息(放在这防止没连接成功一直打印)
			if(0==pub_con_flag)
			{
				log_error("mqtt connect docker failed!\r\n");
			}

        	ret = get_temp_hum(&temp_f,&hum_f);
			if(0==ret)//数据读取成功
			{
				check_temp_limit(fd_oled,hum_f);		//数据读取成功后最先应该检查是否该报警

				oled_show_temp_hum_num(fd_oled,temp_f,hum_f);
				ret=pack_temp_hum(databuf,sizeof(databuf),temp_f,hum_f);
				if(0!=ret)
				{
					log_error("pack_temp_hum failed!\r\n");
					continue;
				}
				if(con_success==pub_con_flag)//连接成功
				{
					ret=publish_message(mosq,&mqtt_data,databuf);
					if(MOSQ_ERR_SUCCESS!=ret)
					{
						pub_con_flag=con_failed;
						log_error("publish_message failed!\r\n");
						continue;
					}
				}
			}

		}
    }
Cleanup:
	mosquitto_disconnect(mosq);
Cleanup_fd:
	oled_close(fd_oled);
	mosquitto_loop_stop(mosq,true);
Cleanup_mosq_obj:
	mosquitto_destroy(mosq);
Cleanup_mosq_lib:
	mosquitto_lib_cleanup();
Cleanup_logger:
	logger_term();

	printf("program will exit!\r\n");
	return ret;
}

void signal_init()
{
	struct sigaction        sigact,sigign;

	sigact.sa_handler = sign_handle;
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = 0;

	sigign.sa_handler = SIG_IGN;
	sigemptyset(&sigign.sa_mask);
	sigign.sa_flags = 0;

	//插入kill,CTRL+C,SIGPIPE处理信号
	sigaction(SIGTERM,&sigact,0);
	sigaction(SIGINT,&sigact,0);
	sigaction(SIGPIPE,&sigign,0);

}

